Learning Transferable Visual Models from Natural Language Supervision
传统:
训练1000个类别,预测就只能限制于这1000个类别,无法扩展。
新增类别还要重新训练、重新标准。——重复工作、拓展能力(泛化能力、迁移能力)差
CLIP:预训练模型直接zreo-shot——给提示就能完成任务
CLIP论文指出:以前的方法不是不行,是资源不到位。——更大的模型、数据。
成名一战:
CLIP在完全不使用ImageNet中所有数据训练的前提下:
直接Zero-shot得到的结果与Resnet在128WImagenet数据训练后效果一样
使用4亿个配对的数据和文本来进行训练,直接爬取的,不标注
现在CLIP下游任务已经很多了,GAN,检测,分割,检索等
不做预测,做对比。
对比学习:
正样本:图像和样本配对,就是正样本对;(上图矩阵对角线)
负样本:图像和样本不配对,图是狗,文本是树;
希望正样本相似度越大越好:让对角线相似度最大。
对比学习效率比预测提高4倍。
合理运用prompt提示。
CLIP在MINIST数据集效果不好,只有89%:因为MINIST是人工合成的,不属于实际场景。
可见,clip比较适合实际常见场景。(zero-shot)
提示:把类别扩展成一句话
跟Resnet50当成平手,但是Resnet50也不是标杆
OpenAi说如果要跟标杆(比如ViT)比较,数据集需要1000X(扩大1000倍)
只能面向常规的,Mnist它效果一般,因为这种数据是人工合成的
面向测试集调参?就跟lmagenet干上了,参数都适合imagenet
import torch
import clip
from PIL import Image
# Load the pre-trained CLIP model
device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load("ViT-B/32", device=device) # 保留路径:C:\Users\HP\.cache\clip
# Load image
image_path = "F:\FNii\VLM\image.png"
image = Image.open(image_path)
# Define your input image and text
image = preprocess(image).unsqueeze(0) # Preprocess your image
text = clip.tokenize(["city","people","park"]) # Tokenize your text,必须是向量
# Encode the image and text
with torch.no_grad():
image_features = model.encode_image(image.to(device))
text_features = model.encode_text(text.to(device))
# Perform similarity calculation
similarity = (100.0 * image_features @ text_features.T).softmax(dim=-1)
# Print the similarity scores
print(similarity)
# unsqueeze(0):在维度0上增加一个维度
# unsqueeze()函数是在张量(Tensor)上操作的方法,它的作用是在指定的维度上增加一个维度。在这里,unsqueeze(0)表示在维度0上增加一个维度。
# 举个例子来说明,假设有一个形状为(3,)的一维张量,即一个包含3个元素的向量。调用unsqueeze(0)后,这个张量的形状将变为(1, 3),即一个包含1行3列的二维张量。
# 这个函数在某些情况下非常有用,例如在进行某些运算时需要保持张量的维度一致,或者在将一维张量作为输入传递给某些需要二维张量的函数时。
# 需要注意的是,unsqueeze()函数返回的是一个新的张量,原始张量并没有被修改。因此,在使用unsqueeze()函数后,需要将返回的新张量赋值给一个变量或者使用它进行后续的操作。
image_path = "F:\FNii\VLM\image.png"
image = Image.open(image_path)
pre_image = preprocess(image)
pre_image.shape
pre_image.unsqueeze(0).shape
from PIL import Image
from transformers import CLIPProcessor,CLIPModel
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")#openai/clip-vit-base-patch32
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")
preprocessor_config.json: 0%| | 0.00/316 [00:00<?, ?B/s]
tokenizer_config.json: 0%| | 0.00/592 [00:00<?, ?B/s]
vocab.json: 0%| | 0.00/862k [00:00<?, ?B/s]
merges.txt: 0%| | 0.00/525k [00:00<?, ?B/s]
tokenizer.json: 0%| | 0.00/2.22M [00:00<?, ?B/s]
special_tokens_map.json: 0%| | 0.00/389 [00:00<?, ?B/s]
import requests
url = "http://images.cocodataset.org/val2017/000000039769.jpg"
image = Image.open(requests.get(url, stream=True).raw)
image
# image = Image.open('F:\FNii\VLM\image.png')
text =['dog','cat','tiger'] # 必须英文
inputs = processor(text=text, images=image, return_tensors="pt", padding=True)
outputs = model(**inputs)
logits_per_image =outputs.logits_per_image# this is the image-text similarity score
logits_per_image # tensor([[18.2806, 23.2766, 21.0254]], grad_fn=<TBackward0>)
probs = logits_per_image.softmax(dim=1)# we can take the softmax to get the label probabilities
for i in range(len(text)):
print(text[i],':',probs[0][i])
dog : tensor(0.0061, grad_fn=<SelectBackward0>) cat : tensor(0.8993, grad_fn=<SelectBackward0>) tiger : tensor(0.0947, grad_fn=<SelectBackward0>)
从文本生成图片